﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Sustainalytics.ScreeningTool.Synchronization
{
    public class ExtraElement
    {
        public string Key { get; }
        public object Value { get; }
        public DateTime? Timestamp { get; }

        public ExtraElement(string key, object value, DateTime? timestamp = null)
        {
            if (value is ITimestamped timestamped)
            {
                value = timestamped.Value;
                timestamp = timestamped.Timestamp;
            }

            Key = key.Replace(".", "");
            Value = GetValue(value);
            Timestamp = timestamp != DateTime.MinValue ? timestamp : null;
        }

        public ExtraElement(string key, ITimestamped timestamped)
            : this(key, timestamped?.Value, timestamped?.Timestamp)
        {
        }

        private static object GetValue(object value)
        {
            switch (value)
            {
                case string s when string.IsNullOrWhiteSpace(s): return null;
                case double d when double.IsNaN(d): return null;
                case decimal d: return (double)d;
                default: return value;
            }
        }
    }

    public class ExtraElementList : List<ExtraElement>
    {
        public void Add(string key, object value, DateTime? timestamp = null)
            => Add(new ExtraElement(key, value, timestamp));

        public void Add<T>(string key, Timestamped<T> timestamped)
            => Add(new ExtraElement(key, timestamped));
    }

    public static class ExtraElementsExtensions
    {
        public static IEnumerable<(string Key, object Value)> WithTimestamps(this IEnumerable<ExtraElement> extraElements)
            => extraElements.SelectMany(x => new[]
            {
                (x.Key, x.Value),
                (Key: $"{x.Key}-Timestamp", Value: x.Timestamp),
            }).Where(x => x.Value != null);

        public static Dictionary<string, object> AsGroupExtraElements(this IEnumerable<ExtraElement> extraElements)
            => extraElements.WithTimestamps().ToDictionary(x => x.Key, x => x.Value);
    }
}
